package com.api.aiyh_guijiu.service;

import aiyh.utils.ApiResult;
import aiyh.utils.Util;
import aiyh.utils.fileUtil.WatermarkPoint;
import aiyh.utils.fileUtil.WatermarkPointEnum;
import aiyh.utils.fileUtil.WritWatermark;
import aiyh.utils.mapUtil.ParaMap;
import aiyh.utils.sqlUtil.sqlResult.impl.PrepSqlResultImpl;
import aiyh.utils.zwl.common.ToolUtil;
import com.api.aiyh_guijiu.dao.ConflictWorkflowDao;
import com.api.aiyh_guijiu.pojo.WorkflowBaseInfoDTO;
import com.api.aiyh_guijiu.pojo.WorkflowConfigDTO;
import com.api.aiyh_guijiu.vo.ConfigInfoVo;
import com.api.aiyh_guijiu.vo.PicPsVO;
import com.api.workflow.constant.RequestAuthenticationConstant;
import com.drew.imaging.ImageMetadataReader;
import com.drew.imaging.ImageProcessingException;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.Tag;
import com.engine.workflow.biz.requestForm.FileBiz;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.h2.util.StringUtils;
import weaver.conn.RecordSet;
import weaver.docs.docs.DocManager;
import weaver.file.ImageFileManager;
import weaver.hrm.User;

import java.awt.*;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

/**
 * @author EBU7-dev1-ayh
 * @create 2021/9/7 0007 12:43
 * workflow queue
 */


public class WorkflowQueueService {
	ToolUtil toolUtil = new ToolUtil();
	ObjectMapper mapper = new ObjectMapper();
	ConflictWorkflowDao conflictWorkflowDao = new ConflictWorkflowDao();


	/**
	 * 查询ps配置参数
	 *
	 * @return 配置信息
	 */
	public String getPicIsPsConfig(String workflowId) {
		ConfigInfoVo ufPsNodeConfig = conflictWorkflowDao.getConfigInfo("uf_ps__node_config", workflowId);
		if (ufPsNodeConfig == null) {
			return ApiResult.successNoData();
		}
		return ApiResult.success(ufPsNodeConfig);
//		String picPsWorkflowId = toolUtil.getSystemParamValue("PIC_PS_WORKFLOW_ID");
//		if (StringUtils.isNullOrEmpty(picPsWorkflowId)) {
//			return ApiResult.successNoData();
//		}
//		String nodeId = toolUtil.getSystemParamValue("PIC_PS_NODE_ID");
//		String fieldName = toolUtil.getSystemParamValue("PIC_PS_FIELD_NAME");
//		List<Integer> watermarkConfig = conflictWorkflowDao.getWatermarkConfig(picPsWorkflowId);
//		Map<String, Object> map = new HashMap<>();
//		map.put("workflowIds", watermarkConfig);
//		map.put("nodeId", nodeId);
//		map.put("fieldName", fieldName);
//		return ApiResult.success(map);
	}

	/**
	 * 查询图片是否经过ps
	 *
	 * @param imgIds 需要查询的图片的id
	 * @return 是否进行ps的分析结果
	 */
	public String getPicIsPs(String imgIds) {
//		通过docId查询到物理文件的id
		String query = "select imagefileid,imagefilename,docid from docimagefile where docid in ( " + imgIds + ")";
		RecordSet rs = new RecordSet();
		rs.executeQuery(query);
		List<PicPsVO> list = new ArrayList<>();
		while (rs.next()) {
			int id = rs.getInt(1);
			String name = rs.getString(2);
			int docId = rs.getInt(3);
			PicPsVO picPsVO = PicPsVO.PicPsVOBuilder.aPicPsVO()
					.docId(docId)
					.fileId(id)
					.fileName(name)
					.build();
//			通过物理文件的id进行获取对应的输入流信息。
//			ImageFileManager imageFileManager = new ImageFileManager();
			//		通过文件id获取输入流
			InputStream inputStreamById = ImageFileManager.getInputStreamById(id);
			try {
//				获取媒体数据
				Metadata metadata = ImageMetadataReader.readMetadata(inputStreamById);
//				遍历Directory对象，每个对象里面包含标签
				for (Directory directory : metadata.getDirectories()) {
					String directoryName = directory.getName();
					System.out.println(directory);
					if ("Photoshop".equalsIgnoreCase(directoryName) || "Adobe JPEG".equalsIgnoreCase(directoryName)
							|| directoryName.contains("Adobe")) {
						if (picPsVO.getScore() > 90) {
							continue;
						}
						picPsVO.setDescribe("图片经过Adobe Photoshop软件，注意审核！");
						picPsVO.setScore(90);
					}
					String model = "";
					for (Tag tag : directory.getTags()) {
						System.out.println(tag);
						if (tag.getDescription() != null && tag.getDescription().toLowerCase().contains("Adobe".toLowerCase())) {
							picPsVO.setDescribe("图片经过Adobe Photoshop软件，注意审核！");
							picPsVO.setScore(70);
							if (picPsVO.getScore() > 70) {
								continue;
							}
						}
						if ("Software".equalsIgnoreCase(tag.getTagName())) {
							if (tag.getDescription().toLowerCase().contains("Adobe".toLowerCase())
									|| tag.getDescription().toLowerCase().contains("Photoshop".toLowerCase())) {
								picPsVO.setDescribe("图片经过Adobe Photoshop软件，注意审核！");
								picPsVO.setScore(100);
							} else {
								if (picPsVO.getScore() > 70) {
									continue;
								}
								picPsVO.setDescribe("图片经过" + tag.getDescription() + "软件，注意审核！");
								picPsVO.setScore(70);
							}
							if (!StringUtils.isNullOrEmpty(model) && picPsVO.getDescribe().contains(model)) {
								picPsVO.setDescribe("");
								picPsVO.setScore(-1);
							}
						}
						if ("Model".equalsIgnoreCase(tag.getTagName())) {
							model = tag.getDescription();
							if (!StringUtils.isNullOrEmpty(picPsVO.getDescribe())) {
								if (picPsVO.getDescribe().contains(tag.getDescription())) {
									picPsVO.setDescribe("");
									picPsVO.setScore(-1);
								}
							}
						}
						if ("User Comment".equalsIgnoreCase(tag.getTagName())) {
							try {
								if (picPsVO.getScore() > 80) {
									continue;
								}
								com.alibaba.fastjson.JSONObject.parseObject(tag.getDescription());
								picPsVO.setDescribe("图片经过手机端图片处理软件，软件未知！请注意审核！");
								picPsVO.setScore(80);
							} catch (Exception e) {
								if (picPsVO.getScore() > 40) {
									continue;
								}
								picPsVO.setDescribe("图片可能经过未知软件！请注意审核！");
								picPsVO.setScore(40);
							}
						}
					}
				}
			} catch (ImageProcessingException | IOException e) {
				e.printStackTrace();
			}
			list.add(picPsVO);
		}
		List<PicPsVO> collect = list.stream().filter(item -> item.getScore() > 0).collect(Collectors.toList());
		return ApiResult.success(collect);
	}

	public String getWorkflowQueue(Map<String, String> param) {
		String workflowId = param.get("workflowId");
		String requestId = param.get("requestId");
		List<Integer> watermarkConfig = conflictWorkflowDao.getWatermarkConfig(workflowId);
		List<WorkflowConfigDTO> workflowConfigDTOS = conflictWorkflowDao.queryConfig(workflowId);
		if (workflowConfigDTOS == null || workflowConfigDTOS.size() == 0) {
			return ApiResult.successNoData();
		}
		WorkflowConfigDTO nowConfig = workflowConfigDTOS.stream().filter(item -> {
			AtomicBoolean flag = new AtomicBoolean(false);
			watermarkConfig.forEach(id -> {
				if (id == item.getWorkflowType()) {
					flag.set(true);
				}
			});
			return flag.get();
		}).collect(Collectors.toList()).get(0);

//		获取当前流程填写的时间信息
		String startTime = param.get("startTime");
		String startDate = param.get("startDate");
		String endTime = param.get("endTime");
		String endDate = param.get("endDate");
		String hrmStr = param.get("hrmStr");
//		如果当前的requestid不是创建节点，则查询数据库信息作为对比条件
		if (!"-1".equals(requestId)) {
			String hrmField = Util.null2String(nowConfig.getHrmField());
			String query = "select * from " + nowConfig.getTablename() + " where requestid = ?";
			RecordSet rs = new RecordSet();
			rs.executeQuery(query, requestId);
			rs.next();
			hrmStr = rs.getString(hrmField);
			startDate = rs.getString(nowConfig.getStartDateField());
			startTime = rs.getString(nowConfig.getStartTimeField());
			endTime = rs.getString(nowConfig.getEndTimeField());
			endDate = rs.getString(nowConfig.getEndDateField());
		}

		List<WorkflowBaseInfoDTO> list = new ArrayList<>();
//		循环查询流程中时间是否存在冲突
		for (WorkflowConfigDTO workflowConfigDTO : workflowConfigDTOS) {
//          查询冲突的流程数据	 流程相关人 查询数据库
			toolUtil.writeErrorLog(hrmStr);
			toolUtil.writeErrorLog(workflowConfigDTO.toString() + "\n");
			for (String hrmId : hrmStr.split(",")) {
				List<WorkflowBaseInfoDTO> workflowBaseInfoDTOList = conflictWorkflowDao.queryConflict(workflowConfigDTO, startTime,
						startDate, endTime, endDate, hrmId, requestId);
				toolUtil.writeErrorLog(workflowBaseInfoDTOList + "\n");
				if (workflowBaseInfoDTOList != null) {
//					toolUtil.writeErrorLog(workflowBaseInfoDTOList.toString());
					list.addAll(workflowBaseInfoDTOList);
				}
			}
		}
		if (list.size() == 0) {
			return ApiResult.successNoData();
		}
		ArrayList<WorkflowBaseInfoDTO> collect = list.stream().collect(
				Collectors.collectingAndThen(
						Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(WorkflowBaseInfoDTO::getRequestid))), ArrayList::new)
		);
//		将查询到的信息进行返回给前端
		return ApiResult.success(collect);
	}


	/**
	 * 给图片添加水印信息
	 *
	 * @param user  user对象
	 * @param param 请求参数
	 * @return 添加水印后的文档信息
	 */
	public String addWaterMark(User user, Map<String, String> param) {
		String fileIds = param.get("fileIds");
		String location = param.get("location");
		String time = param.get("time");
		if (StringUtils.isNullOrEmpty(time)) {
			time = Util.getTime("yyyy-MM-dd HH:mm:ss");
		}
		String pressText = "地点：" + location + "\n" + "时间：" + time;
		String watermarkColor = toolUtil.getSystemParamValue("WATERMARK_COLOR");
		if (StringUtils.isNullOrEmpty(watermarkColor)) {
			watermarkColor = "0,0,0";
		}
		//		处理文字水印的RGB颜色
		String[] RGBStr = watermarkColor.replace("，", ",").split(",");
		int[] RGB = Arrays.stream(RGBStr).mapToInt(Integer::parseInt).toArray();
		if (RGB.length < 3) {
			RGB = new int[]{0, 0, 0};
		}
		int R = RGB[0];
		int G = RGB[1];
		int B = RGB[2];
		if (R < 0) {
			R = 0;
		}
		if (R > 255) {
			R = 255;
		}
		if (G < 0) {
			G = 0;
		}
		if (G > 255) {
			G = 255;
		}
		if (B < 0) {
			B = 0;
		}
		if (B > 255) {
			B = 255;
		}
		Color color = new Color(R, G, B);
		String fontName = toolUtil.getSystemParamValue("FONT_NAME");
		if (StringUtils.isNullOrEmpty(fontName)) {
			fontName = "Microsoft YaHei";
		}
		int fontSize = Util.getIntValue(toolUtil.getSystemParamValue("FONT_SIZE"), 10);
		StringBuilder newIds = new StringBuilder();
		int index = 0;
		//根据fileId 查询物理文件
		String query = "select imagefileid from docimagefile where docid in ( " + fileIds + ")";
		RecordSet rs = new RecordSet();
		rs.executeQuery(query);

		while (rs.next()) {
			int id = rs.getInt(1);
			int newId;
			try {
				toolUtil.writeDebuggerLog("开始添加水印，传递字体大小！");
				newId = WritWatermark.addTextWatermarkById(id, pressText, color, fontName, Font.PLAIN, fontSize
						, new WatermarkPoint(WatermarkPointEnum.RIGHT_BOTTOM), 0, 1, 1.3);
			} catch (IOException e) {
				return ApiResult.error("图片水印添加失败！");
			}
			if (index == 0) {
				newIds.append(newId);
			} else {
				newIds.append(",").append(newId);
			}
			index++;
		}
		//复制原图的权限信息等
		//复制原来的文件信息，并将现有的信息进行绑定
		DocManager docManager = new DocManager();
		String[] picIdStrArr = fileIds.split(",");
		String[] newImgArr = newIds.toString().split(",");
		int[] picIdArr = Arrays.stream(picIdStrArr).mapToInt(Integer::parseInt).toArray();
		StringBuilder newDocIds = new StringBuilder();
		for (int i = 0; i < picIdArr.length; i++) {
			docManager.setId(picIdArr[i]);
//				复制文件
			int newId = 0;
			try {
				newId = docManager.copyDoc(false);
			} catch (Exception e) {
				e.printStackTrace();
				toolUtil.writeErrorLog("file copy fail!");
			}
			if (i == 0) {
				newDocIds.append(newId);
			} else {
				newDocIds.append(",").append(newId);
			}
//				替换复制出来的数据的物理文件关联关系
			PrepSqlResultImpl prepSqlResult = aiyh.utils.Util.createSqlBuilder().updateSql("docimagefile"
					, ParaMap.create().put("imagefileid", newImgArr[i])
					, aiyh.utils.Util.createPrepWhereImpl().whereAnd("docid").whereEqual(newId));
			rs.executeUpdate(prepSqlResult.getSqlStr(), prepSqlResult.getArgs());
		}

		// 替换原来图片的字段
		String isSaveResource = toolUtil.getSystemParamValue("SAVE_RESOURCE");
		String sourceField = toolUtil.getSystemParamValue("RESOURCE_FIELD");
		if (StringUtils.isNullOrEmpty(isSaveResource)) {
			isSaveResource = "0";
		}
		String fieldName = param.get("fieldName");
		String tableName = param.get("tableName");
		String isWrite = param.get("isWrite");
		String isAppend = param.get("isAppend");
//		String sourceField = param.get("sourceField");
		String requestId = param.get("requestId");
		String oldFileIds = param.get("oldFileIds");
		if ("true".equals(isWrite)) {
			if ("true".equals(isAppend)) {
//			//		查询原字段是否存在图片
//				String queryStr = "";
//				try {
//					queryStr = "select " + fieldName + " from " + tableName + " where requestid = ?";
//					rs.executeQuery(queryStr, requestId);
//					rs.next();
//					String oldImg = Util.null2String(rs.getString(1));
//					if (!StringUtils.isNullOrEmpty(oldImg)) {
				newDocIds.append(",").append(oldFileIds);
//					}
//				}catch (Exception e){
//					toolUtil.writeErrorLog("查询错误：" + queryStr);
//				}
			}
			if ("0".equals(isSaveResource)) {
				// 不保存原来的图片
				String update = "update " +
						tableName +
						" set " +
						fieldName +
						" = '" +
						newDocIds +
						"' where " +
						" requestid = ?";
				rs.executeUpdate(update, requestId);
			} else {
				String update = "update " +
						tableName +
						" set " +
						fieldName +
						" = '" +
						newDocIds +
						"' , " +
						sourceField +
						" = '" +
						fileIds +
						"' where " +
						" requestid = ?";
				rs.executeUpdate(update, requestId);
			}
		}

		// 查询新文件信息
		String listType = Util.null2String(String.valueOf(param.get("listType")), "list");
		int requestid = Util.getIntValue(Util.null2String(String.valueOf(param.get("requestid"))), -1);
		int desrequestid = Util.getIntValue(Util.null2String(String.valueOf(param.get("desrequestid"))), -1);
		int isprint = Util.getIntValue(Util.null2String(String.valueOf(param.get("isprint"))), 0);
		int workflowid = Util.getIntValue(Util.null2String(String.valueOf(param.get("workflowid"))), 0);
		String f_weaver_belongto_userid = Util.null2String(String.valueOf(param.get("f_weaver_belongto_userid")));
		String f_weaver_belongto_usertype = Util.null2String(String.valueOf(param.get("f_weaver_belongto_usertype")));
		String authStr = Util.null2String(String.valueOf(param.get(RequestAuthenticationConstant.AUTHORITY_STRING)));
		String authSignatureStr = Util.null2String(String.valueOf(param.get(RequestAuthenticationConstant.AUTHORITY_SIGNATURESTRING)));
		Map<String, Object> paramsMap = new HashMap<>();
		paramsMap.put("user", user);
		Map<String, Object> retobj;
		try {
			retobj = FileBiz.getFileDatas(Util.null2String(newDocIds.toString()), listType, requestid, desrequestid,
					isprint, f_weaver_belongto_userid, f_weaver_belongto_usertype, true, false, authStr, authSignatureStr, paramsMap);
		} catch (Exception e) {
			e.printStackTrace();
			return ApiResult.error("查询附件信息失败：" + e);
		}
		Map<String, Object> result = new HashMap<>();
		result.put("fileData", retobj);
		result.put("fileIds", newDocIds.toString());
		return ApiResult.success(result);
	}


	/**
	 * 获取某个流程需要添加水印的字段和全版本的流程id
	 *
	 * @return 配置信息
	 */
	public String getWatermarkConfig(String workflowId) {
		ConfigInfoVo configInfo = conflictWorkflowDao.getConfigInfo("uf_watermark_cofig", workflowId);
		if (configInfo == null) {
			return ApiResult.successNoData();
		}
		return ApiResult.success(configInfo);
//		Map<String, Object> map = new HashMap<>();
//		String workflowId = toolUtil.getSystemParamValue("PIC_WATERMARK_WORKFLOW_ID");
//		List<Integer> list = conflictWorkflowDao.getWatermarkConfig(workflowId);
//		String picWatermarkField = toolUtil.getSystemParamValue("PIC_WATERMARK_FIELD_NAME");
//		String nodeId = toolUtil.getSystemParamValue("PIC_WATERMARK_NODE_ID");
//		map.put("fieldName", picWatermarkField);
//		map.put("workflowIds", list);
//		map.put("nodeId", nodeId);
//		return ApiResult.success(map);
	}

	/**
	 * 获取泛型的Collection Type
	 *
	 * @param collectionClass 泛型的Collection
	 * @param elementClasses  元素类
	 * @return JavaType Java类型
	 */
	public JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
		return mapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
	}


	/**
	 * 查询需要排查流程时间片段冲突的配置信息
	 *
	 * @param workflowId 流程id
	 * @return 配置信息
	 */
	public String getWorkflowConflictConfig(String workflowId) {
		Map<String, Object> map = new HashMap<>();
		List<Integer> watermarkConfig = conflictWorkflowDao.getWatermarkConfig(workflowId);
		WorkflowConfigDTO workflowConfig = conflictWorkflowDao.getWorkflowConfig(workflowId);
		map.put("workflowIds", watermarkConfig);
		map.put("workflowConfig", workflowConfig);
		return ApiResult.success(map);
	}
}
